home *** CD-ROM | disk | FTP | other *** search
- #ifdef lint
- static char *SCCSid = "%W% (NCSA) %G%";
- #endif
-
- /*
- *
- * Virtual Screen Kernel Interface
- * (vsinterf.c)
- *
- * by Gaige B. Paulsen
- *
- * This file contains the control and interface calls for the NCSA
- * Virtual Screen Kernal.
- *
- * VSinit(maxwidth) - Initialize the VSK
- * VSnewscreen(maxlines,scrnsave) - Initialize a new screen.
- * VSdetach(w) - Detach screen w
- * VSredraw(w,x1,y1,x2,y2) - redraw region for window w
- * VSwrite(w,ptr,len) - write text @ptr, length len
- * VSclear(w) - clear w's real screen
- * VSkbsend(w,k,echo) - send keycode k's rep. out window w (w/echo if req.)
- * VSclearall(w) - clear w's real and saved screen
- * VSreset(w) - reset w's emulator (as per TERM)
- * VSgetline(w,y) - get a ptr to w's line y
- * VSsetrgn(w,x1,y1,x2,y2) - set local display region
- * VSscrolback(w,n) - scrolls window w back n lines
- * VSscrolforward(w,n) - scrolls window w forward n lines
- * VSscrolleft(w,n) - scrolls window w left n columns
- * VSscrolright(w,n) - scrolls window w right n columns
- * VSscrolcontrol(w,scrlon,offtop) - sets scroll vars for w
- * VSgetrgn(w,&x1,&y1,&x2,&y2) - returns set region
- * VSsnapshot(w) - takes a snapshot of w
- * VSgetlines(w) - Returns current # of lines
- * VSsetlines(w, lines) - Sets the current # of lines to lines
- *
- * Version Date Notes
- * ------- ------ ---------------------------------------------------
- * 0.01 861102 Initial coding -GBP
- * 0.10 861113 Added some actual program to this file -GBP
- * 0.15 861114 Initiated Kludge Operation-GBP
- * 0.50 8611VSPBOTTOM Parameters added to VSnewscreen -GBP
- * 0.90 870203 Added the kbsend routine -GBP
- * 2.1 871130 NCSA Telnet 2.1 -GBP
- * 2.2 880715 NCSA Telnet 2.2 -GBP
- *
- */
-
- #define VSMASTER
-
- #include <Files.h> /* BYU 2.4.18 MPW */
- #include <QuickDraw.h>
- #include <Controls.h>
- #include <Memory.h>
- #include <ToolUtils.h> /* BYU 2.4.18 - for GetIndString() */
-
- #include <String.h>
- #include <Strings.h> /* BYU 2.4.15 MPW */
- #include "mpw.h" /* NCSA 2.5 */
- #include <Resources.h> /* NCSA 2.5 */
- #include "rsmac.h"
- #include "vsem.h"
- #include "vsdata.h"
- #include "vskeys.h"
- #include "vsinit.h"
- #include "vsintern.h"
- #include "Wind.h"
- #define DEBUGMAC
- extern int netwrite();
- extern int findbyWind();
- extern WindRec *screens;
-
- extern int defaultv; /* BYU 2.4.18 - for capture session to file */
-
- int
- /* Internal variables for use in managing windows */
- VSmax = 0, /* max nr screens allowed */
- VSinuse = 0; /* nr screens actually in existence */
- VSscrndata *VSscreens;
-
- int VSinit
- (
- int max /* max nr screens to allow */
- )
- /* initializes virtual screen and window handling. */
- {
- int i;
-
- RSinitall(max);
- VSmax = max;
- VSIwn = 0;
- if ((VSscreens = (VSscrndata *) NewPtr(max * sizeof(VSscrndata))) == 0L)
- return(-2);
- for (i = 0; i < max; i++)
- {
- VSscreens[i].loc = 0L;
- VSscreens[i].stat = 0;
- } /* for */
- return(0);
- } /* VSinit */
-
-
- int VSiscapturing(int w) { /* BYU 2.4.18 */
- return(VSscreens[w].captureRN); /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
-
-
- #define CAPT_RESOURCE_ID 23238 /* BYU 2.4.18 */
- #define GetStrRes(x) (Str255 **)GetResource('STR ',(x)); /* NCSA 2.5 */
- #define FileSTR 1024 /* NCSA 2.5: name of capture file */
-
- int VSopencapture(int scrn_num, int w) { /* BYU 2.4.18 */
- short fstat; /* BYU 2.4.18 */
- unsigned char capturefile[256]; /* NCSA 2.5 */
- char numstring[4]; /* BYU 2.4.18 */
- Str255 **fileR; /* NCSA 2.5 */
-
- /* GetIndString(capturefile,CAPT_RESOURCE_ID,1); */ /* NCSA 2.5 */
- fileR=GetStrRes( FileSTR); /* NCSA 2.5 */
- HLock((Handle)fileR); /* NCSA 2.5 */
- movmem(*fileR,capturefile,255); /* NCSA 2.5 */
- HUnlock((Handle)fileR); /* NCSA 2.5 */
- ReleaseResource((Handle)fileR); /* NCSA 2.5 */
-
- sprintf(numstring,"%d",scrn_num); /* BYU 2.4.18 */
- p2cstr(capturefile); /* BYU 2.4.18 */
- strcat((char*) capturefile,numstring); /* BYU 2.4.18 */
- c2pstr(capturefile); /* BYU 2.4.18 */
- Create(capturefile, defaultv, 'EDIT', 'TEXT'); /* BYU 2.4.18 */
- fstat = FSOpen(capturefile, defaultv, /* BYU 2.4.18 */
- &VSscreens[w].captureRN); /* BYU 2.4.18 */
- if (!fstat) /* BYU 2.4.18 */
- SetEOF(VSscreens[w].captureRN, (long) 0); /* BYU 2.4.18 */
- return(fstat); /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
-
- VSclosecapture(int w) { /* BYU 2.4.18 */
- FSClose(VSscreens[w].captureRN); /* BYU 2.4.18 */
- VSscreens[w].captureRN = 0; /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
-
- VScapture(unsigned char *ptr, int len) { /* BYU 2.4.18 */
- long ln = len; /* BYU 2.4.18 */
- if (VSscreens[VSIwn].captureRN) { /* BYU 2.4.18 */
- unsigned char captbuf[512]; /* BYU 2.4.18 */
- unsigned char *ptr2,*ptr3; /* BYU 2.4.18 */
- ptr2 = ptr; /* BYU 2.4.18 */
- ptr3 = &captbuf[0]; /* BYU 2.4.18 */
- for (len = 0; len < ln; len++) { /* BYU 2.4.18 */
- if (*ptr2 >= 32 || /* BYU 2.4.18 */
- *ptr2 == 13 || /* BYU 2.4.18 */
- *ptr2 == 9) /* BYU 2.4.18 */
- *(ptr3++) = *(ptr2++); /* BYU 2.4.18 */
- else { /* BYU 2.4.18 */
- ptr2++; /* BYU 2.4.18 */
- ln--; /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
- if (ln > 0) { /* BYU 2.4.18 */
- if (FSWrite(VSscreens[VSIwn].captureRN, &ln, captbuf)) { /* BYU 2.4.18 */
- FSClose(VSscreens[VSIwn].captureRN); /* BYU 2.4.18 */
- VSscreens[VSIwn].captureRN = 0; /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
- } /* BYU 2.4.18 */
-
- int VSvalids
- (
- int w
- )
- /* validates a virtual screen number and sets it as the
- current screen for subsequent operations if success.
- Returns 0 iff success. */
- {
- if (VSinuse == 0)
- return(-5); /* -5=no ports in use */
- if (VSIwn == w)
- return(0); /* Currently set to that window */
- if ((w > VSmax) || (w < 0))
- return(-6); /* blown out the top of the stuff */
- VSIwn = w;
- if (VSscreens[w].stat != 1)
- return(-3);/* not currently active */
- VSIw = VSscreens[w].loc;
- if (VSIw == 0L)
- return(-3); /* no space allocated */
- return(0);
- } /* VSvalids */
-
- VSscrn *VSwhereis(i)
- int i; /* screen number */
- /* returns a pointer to the structure for the specified screen. */
- {
- VSvalids(i);
- return(VSIw);
- } /* VSwhereis */
-
- void VSIclrbuf
- (
- void
- )
- /* clears out the text and attribute buffers for the current screen.
- All text characters are set to blanks, and all attribute bytes
- are set to zero. Doesn't update the display. */
- {
- register int j, i;
- register char *ta, *tx;
-
- for (i = 0; i <= VSIw->lines; i++)
- {
- ta = &VSIw->attrst[i]->text[0];
- tx = &VSIw->linest[i]->text[0];
- for (j = 0; j <= VSIw->allwidth; j++)
- {
- *ta++ = 0;
- *tx++ = ' ';
- } /* for */
- } /* for */
- } /* VSIclrbuf */
-
- int VSnewscreen
- (
- int maxlines, /* max lines to save in scrollback buffer */
- int screensave, /* whether to have a scrollback buffer */
- int maxwid, /* number of columns on screen */
- int IDC, /* NCSA 2.5:whether to be smart and scroll things on character
- insertion/deletion. Currently always passed as 1 (in the
- only call, from RSnewwindow in rsmac.c). Just as well,
- because the two places (both in vsintern.c) where this does
- matter don't do correct redrawing otherwise. */
- int forcesave /* NCSA 2.5: force lines to be saved */
- )
- /* creates a new virtual screen, and returns its number. */
- {
- VSlinePtr tt;
-
- if (maxlines < VSDEFLINES)
- maxlines = VSDEFLINES;
-
- if (VSinuse >= VSmax)
- /* too many screens in existence */
- return(-1);
- VSIwn = 0;
- while ((VSIwn < VSmax) && (VSscreens[VSIwn].stat == 1))
- VSIwn++;
- if (VSIwn >= VSmax)
- /* shouldn't occur? */
- return(-1);
-
- if (VSscreens[VSIwn].stat == 2)
- {
- /* recycling an old screen structure */
- VSIw = VSscreens[VSIwn].loc;
- if (VSIw == 0L)
- return(-7);
- }
- else
- /* create a new screen structure */
- if ((VSscreens[VSIwn].loc = VSIw = (VSscrn *) NewPtr(sizeof(VSscrn))) == 0L)
- {
- VSscreens[VSIwn].loc = 0L;
- return(-2);
- } /* if */
- if (VSscreens[VSIwn].stat != 2)
- {
- VSIw->maxlines = maxlines;
- VSIw->numlines = 0;
- } /* if */
- VSscreens[VSIwn].captureRN = 0; /* BYU 2.4.18 - capture file's RefNum */
- VSIw->maxwidth = maxwid - 1;
- VSIw->allwidth = maxwid - 1;
- VSIw->savelines = screensave;
- VSIw->forcesave = forcesave; /* NCSA 2.5 */
- VSIw->attrib = 0;
- VSIw->Pattrib = -1; /* initially no saved attribute */
- VSIw->x = 0;
- VSIw->y = 0;
- VSIw->charset = 0;
- VSIw->G0 = 0;
- VSIw->G1 = 1;
- VSIw->VSIDC = IDC;
- VSIw->DECAWM = 0;
- VSIw->DECCKM = 0;
- VSIw->DECPAM = 0;
- VSIw->DECORG = 0;
- VSIw->IRM = 0;
- VSIw->escflg = 0;
- VSIw->top = 0;
- VSIw->bottom = 23;
- VSIw->parmptr = 0;
- VSIw->Rtop = 0;
- VSIw->Rleft = 0;
- VSIw->Rright = 79;
- VSIw->Rbottom = 23;
- VSIw->ESscroll = 1;
- /* shouldn't the following three statements be conditional on
- *not* recycling an existing screen structure? */
- VSIw->lines = 23;
- VSIw->linest = VSInewlinearray(VSIw->lines + 1);
- VSIw->attrst = VSInewlinearray(VSIw->lines + 1);
- VSinuse++;
-
- if (VSscreens[VSIwn].stat == 2)
- {
- VSscreens[VSIwn].stat = 1;
- VSIclrbuf();
- VSItabinit();
- return(VSIwn);
- } /* if */
- VSscreens[VSIwn].stat = 1;
-
- VSIw->tabs = (char *) NewPtr(maxwid);
-
- /*
- * Fill initial scrollback buffer and screen storage space.
- *
- * Memory allocation rules:
- * line->mem == 0 if not a memory allocation, line->mem == 1 if it is the first
- * VSline in a block (indeterminate size, may be size == 1)
- *
- * attributes array is ALWAYS allocated as one block. Internally represented and
- * manipulated as a linked list of lines, but only one of the lines will have
- * line->mem == 1. This list is always supposed to be circular (it is never
- * extended, as attributes are never scrolled back).
- *
- * scrollback and screen line buffer space is allocated in large blocks. Each
- * block will have line->mem == 1 if the pointer to that VSline is "free"able.
- * This list will either be circular (which means it has reached its full size),
- * or it will have a NULL next field at the end. During scrolling, the end may
- * be augmented until VSIw->numlines > VSIw->maxlines or we run out of memory.
- * Typically allocate memory 100 lines at a time in two blocks, one is the VSline
- * list, the other is the mem for the character storage.
- *
- */
- if (screensave)
- tt = VSInewlines(VSIw->lines + 1 + VSDEFLINES); /* screen lines plus some initial preallocated scrollback space */
- else
- tt = VSInewlines(VSIw->lines + 1); /* screen lines, no scrollback */
- if (!tt)
- return(-2);
- VSIw->buftop = tt;
- VSIw->scrntop = VSIw->buftop;
-
- tt = VSInewlines(VSIw->lines + 1); /* new space for attributes (these are never scrolled back) */
- if (!tt)
- return(-2);
- VSIw->attrst[0] = tt;
- VSIlistndx(VSIw->scrntop, VSIw->attrst[0]); /* Set up screen arrays */
- VSIw->attrst[0]->prev = VSIw->attrst[VSIw->lines]; /* make attribute list circular, since it is never extended */
- VSIw->attrst[VSIw->lines]->next = VSIw->attrst[0];
- if (!screensave)
- {
- /* make text line list circular to indicate no extensions */
- VSIw->linest[0]->prev = VSIw->linest[VSIw->lines];
- VSIw->linest[VSIw->lines]->next = VSIw->linest[0];
- } /* if */
- VSIclrbuf();
- VSItabinit();
- VSIw->vistop = VSIw->scrntop; /* initial view = screen */
- #ifdef DEBUGPC
- VSckconsist(1, 1);
- #endif DEBUGPC
- return(VSIwn);
- } /* VSnewscreen */
-
- VSdestroy(w)
- int w; /* screen number */
- /* gets rid of a virtual screen. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- VSIfreelines();
- VSIfreelinelist(VSIw->attrst[0]);
- DisposPtr((Ptr) VSIw->attrst);
- DisposPtr((Ptr) VSIw->linest);
- DisposPtr(VSIw->tabs);
- DisposPtr((Ptr) VSIw);
- VSscreens[w].stat = 0;
- VSIwn = -1;
- VSinuse--; /* SCA '87 */
- return(0);
- } /* VSdestroy */
-
- #ifdef DEBUGPC
- int VSckconsist(out,verbose)
- int out,verbose;
- {
- VSlinePtr topa, topt, a, t;
- int line, i;
-
- for (i=0; i<VSmax; i++) { /* For all possible screens... */
- switch( VSscreens[i].stat) {
- case 0:
- if (out && verbose) printf("Screen %d inactive\n",i);
- break;
- case 1:
- if (out) printf("Screen %d active\n",i);
- VSvalids(i);
-
- topa=VSIw->attrst[ 0]->prev; topt=VSIw->linest[ 0]->prev;
- a = VSIw->attrst[0]->next; t= VSIw->linest[0]->next;
-
- if (topa && out) printf(" Attrib thinks its circular\n");
- if (topa != VSIw->attrst[VSIw->lines])
- printf("***********BUT IT'S NOT*************\n");
- for (line=1; line<=VSIw->lines; line++) {
- if (a != VSIw->attrst[ line]) {
- if (out) printf(" Attrib line %d is wrong !\n", line);
- else return(-1);
- }
- a = a->next;
- if ( !a) {
- if (out) printf(" Attrib line %d is NULL\n", line);
- else if (!out && line!=VSIw->lines) return(-2);
- }
- }
-
- if (topt && out) printf(" Linest thinks its circular\n");
- if (VSIw->linest[VSIw->lines]->next) printf(" More than VSIw->lines lines.... \n");
- for (line=1; line<=VSIw->lines; line++) {
- if (t != VSIw->linest[ line]) {
- if (out) printf(" Linest line %d is wrong !\n", line);
- else return (-3);
- }
- t = t->next;
- if ( !t) {
- if (out) printf(" Linest line %d is NULL\n", line);
- else if (line!=VSIw->lines) return(-4);
- }
- }
- if (VSIw->numlines >0) {
- if (out)
- printf(" Thinks that there is scrollback of %d lines ", VSIw->numlines);
- t= VSIw->linest[VSIw->lines]->next;
- line=0;
- while ( t!=0L && t!=VSIw->buftop) {
- t=t->next;
- line++;
- }
- if (out) printf(" [ Actual is %d ]\n", line);
- if (out && t==0L) printf(" Lines end in a null\n");
- if (out && t==VSIw->buftop) printf(" Lines end in a wraparound\n");
- }
- else if (out) printf(" There is no scrollback");
- break;
- case 2:
- if (out && verbose) printf("Screen %d detached\n",i);
- break;
- default:
- if (out) printf("Screen %d invalid stat\n",i);
- break;
- }
- }
- return(0);
- }
- #endif DEBUGPC
-
-
- #ifdef USEDETACH
- VSdetach(w)
- int w;
- {
- if (VSscreens[w].captureRN) /* BYU 2.4.18 */
- FSClose(VSscreens[w].captureRN); /* BYU 2.4.18 */
- if (VSscreens[w].stat!=1) return(-1);
- VSscreens[w].stat=2;
- VSIwn = -1;
- VSinuse--; /* SCA '87 */
- }
- #else
-
- void VSdetach
- (
- int w
- )
- /* this version doesn't try to keep the screen storage for reuse. */
- {
- VSdestroy(w);
- } /* VSdetach */
-
- #endif
-
- int VSredraw
- (
- int w, /* window to redraw */
- int x1, /* bounds of area to redraw, relative to visible region */
- int y1,
- int x2,
- int y2
- )
- /* redisplays the specified portion of a virtual screen. */
- {
- char *pt, *pa;
- int cc, cm;
- char lc, la;
- register VSlinePtr yp;
- register int y;
- int ox, tx1, tx2, ty1, ty2, tn = -1, offset;
-
- if (VSvalids(w) != 0)
- return(-3);
- VSIcuroff(w); /* temporarily hide cursor */
-
- x1 += VSIw->Rleft; x2 += VSIw->Rleft; /* Make local coords global again */
- y1 += VSIw->Rtop; y2 += VSIw->Rtop;
-
- if (x2 < 0)
- x2 = 0;
- if (x1 < 0)
- x1 = 0;
- if (x2 > VSIw->maxwidth)
- x2 = VSIw->maxwidth;
- if (x1 > VSIw->maxwidth)
- x1 = VSIw->maxwidth;
- if (y2 < -VSIw->numlines)
- y2 = -VSIw->numlines; /* limit to amount of scrollback */
- if (y1 < -VSIw->numlines)
- y1 = -VSIw->numlines;
- if (y2 > VSIw->lines)
- y2 = VSIw->lines;
- if (y1 > VSIw->lines)
- y1 = VSIw->lines;
-
- tx1 = x1; tx2 = x2; ty1 = y1; ty2 = y2; /* Set up to clip redraw area to visible area */
- if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset))
- RSerase(w, tx1, ty1, tx2, ty2); /* Erase the offending area */
-
- /* draw visible part of scrollback buffer */
- if (y1 < 0)
- {
- yp = VSIw->vistop;
- y = y1 - VSIw->Rtop;
- while (y-- > 0)
- yp = yp->next; /* Get pointer to top line we need */
- } /* if */
- y = y1;
- while ((y < 0) && (y <= y2))
- {
- ox = tx1 = x1; tx2 = x2; ty1 = ty2 = y; tn = -1;
- if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset))
- RSdraw(w, tx1, ty1, 0, tn, &yp->text[ox + offset]);
- yp = yp->next;
- y++;
- } /* while */
- /* draw visible part of on-screen buffer, taking account of attributes */
- while (y <= y2)
- {
- pt = &VSIw->linest[y]->text[x2]; /* text pointer */
- pa = &VSIw->attrst[y]->text[x2]; /* attribute pointer */
- cm = x2; /* start of a run of characters */
- cc = 1; /* length of the run */
- lc = *pt; /* the last character examined */
- la = *pa; /* the attributes of the last character examined */
- while (cm >= x1)
- {
- if ((lc == ' ') && (la == 0))
- {
- /* skip blank areas of the screen (runs of spaces with no attributes) */
- while((cm > x1) && (*(pt - 1) == ' ') && (*(pa - 1) == 0))
- {
- pa--;
- pt--;
- cm--;
- cc++;
- } /* while */
- pa--;
- pt--;
- cm--;
- cc = 1;
- lc = *pt;
- la = *pa;
- continue;
- } /* if */
- /* find a run of characters with the same attributes */
- while((cm > x1) && (la == *(pa - 1)))
- {
- pa--;
- pt--;
- cm--;
- cc++;
- } /* while */
- if (cm >= x1)
- /* draw the run */
- VSIdraw(w, cm, y, la, cc, pt);
- pa--;
- pt--;
- cm--;
- cc = 1;
- lc = *pt;
- la = *pa;
- } /* while */
- y++;
- } /* while */
- VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */
-
- tx1 = ty1 = 0;
- tn = 132;
- if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset))
- RSdrawsep(w, ty1, 1); /* Draw Separator */
-
- return(0);
- } /* VSredraw */
-
- int VSwrite
- (
- int w, /* screen to draw into */
- char *ptr, /* pointer to text string */
- int len /* length of text string */
- )
- /* sends a stream of characters to the specified window. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- VSIcuroff(w); /* hide cursor momentarily */
- VSem(ptr, len); /* interpret the character stream */
- VSIcurson(w, VSIw->x, VSIw->y, 1); /* restore cursor, force it to be visible. */
- return(0);
- } /* VSwrite */
-
- VSclear(w)
- int w;
- /* clears the screen and homes the cursor. Not used. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- VSIes(); /* clear screen */
- VSIw->x = VSIw->y = 0; /* home cursor */
- VSIcurson(w, VSIw->x, VSIw->y, 1); /* Force Move */
- return(0);
- } /* VSclear */
-
- void VSpossend
- (
- int w, /* affected screen */
- int x, /* column to move to */
- int y, /* line to move to */
- int echo /* local echo flag */
- )
- /* sends a stream of VT100 cursor-movement sequences to move the
- cursor on the specified screen to the specified position. */
- {
- static char
- VSkbax[] = "\033O ", /* prefix for auxiliary code */
- VSkban[] = "\033[ "; /* prefix for arrows normal */
- char *vskptr;
-
- if (VSvalids(w) != 0)
- return;
-
- if (VSIw->DECPAM && VSIw->DECCKM)
- vskptr = VSkbax;
- else
- vskptr = VSkban;
- if (x < 0 || y < 0 || x > VSIw->maxwidth || y > VSIw->lines)
- return;
- /* convert x and y to relative distance to move */
- x -= VSIw->x;
- y -= VSIw->y;
-
- vskptr[2] = 'B'; /* cursor down */
- while (y > 0)
- {
- y--;
- RSsendstring(w, vskptr, 3);
- } /* while */
- vskptr[2] = 'A'; /* cursor up */
- while (y < 0)
- {
- y++;
- RSsendstring(w, vskptr, 3);
- } /* while */
- vskptr[2] = 'C'; /* cursor right */
- while (x > 0)
- {
- x--;
- RSsendstring(w, vskptr, 3);
- } /* while */
- vskptr[2] = 'D'; /* cursor left */
- while (x < 0)
- {
- x++;
- RSsendstring(w, vskptr, 3);
- } /* while */
-
- if (echo)
- {
- VSIcuroff(w);
- VSIw->x = x;
- VSIw->y = y;
- VSIcurson(w, VSIw->x, VSIw->y, 1); /* Force Move */
- } /* if */
- } /* VSpossend */
-
- char VSkbsend
- (
- int w, /* active window */
- unsigned char k, /* special key code if > 128, else ascii code */
- int echo /* local echo flag */
- )
- /* sends the appropriate sequence for the specified key, taking due
- account of terminal mode settings. */
- {
- static char
- VSkbkn[] = "\033O ", /* prefix for keypad normal */
- VSkbax[] = "\033O ", /* prefix for auxiliary code*/
- VSkban[] = "\033[ ", /* prefix for arrows normal */
- VSkbfn[] = "\033O ", /* prefix for function keys */ /* BYU 2.4.12 */
- VSk220[] = "\033[ ~"; /* prefix for vt220 keys */ /* BYU 2.4.12 */
- char *vskptr;
- int vskplen;
-
-
- if (VSvalids(w) != 0)
- return(-3);
- if (k < VSF10) /* BYU 2.4.12 */
- /* 7-bit ascii code -- send as is */
- RSsendstring(w, &k, 1);
-
- if ((k > VSLT) && (k < VSF1) && (!VSIw->DECPAM))
- {
- RSsendstring(w, &VSIkpxlate[0][k - VSUP], 1);
- if (echo)
- VSwrite(w, &VSIkpxlate[0][k - VSUP], 1);
- if (k == VSKE)
- RSsendstring(w, "\012", 1);
- return(0);
- } /* if */
- if (VSIw->DECPAM && VSIw->DECCKM)
- {
- /* aux kp mode */
- vskptr = VSkbax;
- vskplen = 3;
- vskptr[2] = VSIkpxlate[1][k - VSUP]; /* BYU 2.4.12 */
- }
- else if (k < VSUP) { /* BYU 2.4.12 */
- vskptr = VSk220; /* BYU 2.4.12 */
- vskplen = VSIkplen[k - VSF10]; /* BYU 2.4.12 */
- vskptr[2] = VSIkpxlate2[k - VSF10]; /* BYU 2.4.12 */
- vskptr[3] = VSIkpxlate3[k - VSF10]; /* BYU 2.4.12 */
- } else { /* BYU 2.4.12 */
- vskplen = 3; /* BYU 2.4.12 */
- if (k < VSK0) /* BYU 2.4.12 */
- vskptr = VSkban; /* BYU 2.4.12 */
- else if (k < VSF1) /* BYU 2.4.12 */
- vskptr = VSkbkn; /* BYU 2.4.12 */
- else /* BYU 2.4.12 */
- vskptr = VSkbfn; /* BYU 2.4.12 */
- /* BYU 2.4.12 */
- vskptr[2] = VSIkpxlate[1][k - VSUP]; /* BYU 2.4.12 */
- } /* BYU 2.4.12 */
-
- RSsendstring(w, vskptr, vskplen);
- if (echo)
- VSwrite(w, vskptr, vskplen);
- return(0);
- } /* VSkbsend */
-
- VSclearall(w)
- int w;
- /* doesn't seem to do anything interesting. Not used. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- return(0);
- } /* VSclearall */
-
- int VSreset
- (
- int w
- )
- /* resets virtual terminal settings to default state, clears screen
- and homes cursor. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- VSIreset(); /* causes cursor to disappear */
- VSIcurson(w, VSIw->x, VSIw->y, 1); /* redisplay cursor at home position */
- return(0);
- } /* VSreset */
-
- char *VSgetline(w, y)
- int w, y;
- /* returns a pointer to the text for the specified on-screen line.
- Doesn't work for negative values of y (i e lines in the
- scrollback area). Not used. */
- {
- if (VSvalids(w) != 0)
- return((char *) -3);
- return(VSIw->linest[y]->text);
- } /* VSgetline */
-
- void VSscrolright
- (
- int w,
- int n /* number of columns to scroll */
- )
- /* moves the view of the virtual screen within its window the
- specified number of columns to the right. */
- {
- int sn, lmmax;
-
- if (VSvalids(w) != 0)
- return;
-
- /* limit scroll amount against number of invisible columns */
- lmmax = VSIw->maxwidth - (VSIw->Rright - VSIw->Rleft);
- if (VSIw->Rleft + n > lmmax)
- n = lmmax - VSIw->Rleft; /* can't scroll any further right than this */
- if (n == 0)
- return; /* Do nothing if appropriate */
-
- VSIcuroff(w); /* temporarily hide cursor */
- VSIw->Rleft += n; /* update visible region */
- VSIw->Rright += n;
- sn = VSIw->Rbottom - VSIw->Rtop;
- RSmargininfo(w, lmmax, VSIw->Rleft); /* update horizontal scroll bar */
- RSdelcols(w, n); /* scroll the window contents */
- VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */
- /* redraw newly-revealed portion of screen */
- VSredraw(w, (VSIw->Rright - VSIw->Rleft) - n, 0, (VSIw->Rright - VSIw->Rleft), sn);
- } /* VSscrolright */
-
- void VSscrolleft
- (
- int w,
- int n /* number of columns to scroll */
- )
- /* moves the view of the virtual screen within its window the
- specified number of columns to the left. */
- {
- int sn, lmmax;
-
- if (VSvalids(w) != 0)
- return;
-
- lmmax = VSIw->maxwidth - (VSIw->Rright - VSIw->Rleft); /* number of invisible columns */
-
- if (n > VSIw->Rleft)
- n = VSIw->Rleft; /* can't scroll any further left than this */
- if (n == 0)
- return; /* Do nothing if appropriate */
-
- VSIcuroff(w); /* temporarily hide cursor */
- VSIw->Rleft -= n; /* update visible region */
- VSIw->Rright -= n;
- sn = VSIw->Rbottom - VSIw->Rtop;
- RSmargininfo(w, lmmax, VSIw->Rleft); /* update horizontal scroll bar */
- RSinscols(w, n); /* scroll the window contents */
- VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */
- VSredraw(w, 0, 0, n, sn); /* redraw newly-revealed portion of screen */
- } /* VSscrolleft */
-
- int VSscrolback
- (
- int w, /* which window */
- int in /* number of lines to scroll */
- )
- /* moves the view of the virtual screen within its window the
- specified number of lines upwards. */
- {
- int sn, n;
-
- n = in;
-
- if (VSvalids(w) != 0)
- return(-3);
-
- if (VSIw->numlines < (n - VSIw->Rtop))
- n = VSIw->Rtop + VSIw->numlines; /* can't scroll back any further than this */
- if (n <= 0)
- return(0); /* Dont be scrollin' no lines.... */
-
- VSIcuroff(w); /* temporarily hide cursor */
-
- VSIw->Rtop = VSIw->Rtop - n; /* adjust the visible region */
- VSIw->Rbottom = VSIw->Rbottom - n;
-
- /* find the line list element for the new topmost visible line */
- sn = n;
- while (sn-- > 0)
- {
- #ifdef DEBUGMAC
- if (VSIw->vistop->prev == 0L)
- DebugStr("\pVSscrolback -- something wrong with linked list structure");
- #endif DEBUGMAC
- VSIw->vistop = VSIw->vistop->prev;
- } /* while */
-
- sn = VSIw->Rbottom - VSIw->Rtop;
- /* update vertical scroll bar */
- RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
-
- if (n <= VSIw->lines)
- {
- RSinslines(w, 0, sn, n, 0); /* scroll, preserving current selection */
- VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */
- VSredraw(w, 0, 0, VSIw->maxwidth, n - 1); /* redraw newly-revealed portion */
- }
- else
- /* currently-visible contents scrolled completely off the screen--
- just redraw everything */
- VSredraw(w, 0, 0, VSIw->maxwidth, sn);
-
- return(0);
- } /* VSscrolback */
-
- int VSscrolforward
- (
- int w, /* which window */
- int n /* number of lines to scroll */
- )
- /* moves the view of the virtual screen within its window the
- specified number of lines downwards. */
- {
- int sn;
-
- if (VSvalids(w) != 0)
- return(-3);
-
- if (n > VSIw->lines - VSIw->Rbottom)
- n = VSIw->lines - VSIw->Rbottom; /* can't scroll any further forward than this */
- if (n <= 0)
- return(0); /* Dont be scrollin' no lines.... */
-
- VSIcuroff(w); /* temporarily hide cursor */
-
- VSIw->Rtop = n + VSIw->Rtop; /* adjust the visible region */
- VSIw->Rbottom = n + VSIw->Rbottom;
-
- /* find the line list element for the new topmost visible line */
- sn = n;
- while (sn-- > 0)
- {
- #ifdef DEBUGMAC
- if (VSIw->vistop->next == nil)
- DebugStr("\pVSscrolforward -- something wrong with linked list structure");
- #endif DEBUGMAC
- VSIw->vistop = VSIw->vistop->next;
- } /* while */
-
- sn = VSIw->Rbottom - VSIw->Rtop;
- /* update vertical scroll bar */
- RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
-
- if (n <= VSIw->lines)
- {
- RSdellines(w, 0, sn, n, 0); /* scroll, preserving current selection */
- VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */
- VSredraw(w, 0, (sn + 1) - n, VSIw->maxwidth, sn); /* redraw newly-revealed portion */
- } /* if */
- else
- /* currently-visible contents scrolled completely off the screen--
- just redraw everything */
- VSredraw(w, 0, 0, VSIw->maxwidth, sn);
-
- return(0);
- } /* VSscrolforward */
-
- int VSsetrgn
- (
- int w,
- int x1, /* leftmost column */
- int y1, /* uppermost line */
- int x2, /* rightmost column */
- int y2 /* bottommost line */
- )
- /* sets the visible region for the specified virtual screen
- in its window, scrolling its contents as appropriate. Assumes
- that either the vertical bounds or the height of the region has
- changed, but not both, and similarly that the horizontal bounds
- or the width has changed, but not both. */
- {
- int n, offset;
-
- if (VSvalids(w) != 0)
- return(-3);
-
- VSIw->Rbottom = VSIw->Rtop + (y2 - y1); /* make change in height of visible region first */
-
- if (x2 > VSIw->maxwidth)
- {
- /* trying to make columns visible which aren't there--
- adjust the left and right boundaries to avoid this */
- n = x2 - VSIw->maxwidth; /* how far to adjust to the left */
- if (n > x1)
- n = x1; /* but I'd rather have unused columns on the right than on the left */
- x1 -= n; /* Adjust left */
- x2 -= n; /* Adjust right */
- } /* if */
-
- if (VSIw->Rleft != x1)
- {
- /* left margin changed -- scroll horizontally */
- /* (assume width of region hasn't also changed) */
- n = x1 - VSIw->Rleft;
- if (n > 0)
- VSscrolright(w, n);
- else
- VSscrolleft(w, -n);
- }
- else
- /* just update horizontal scroll bar limits for new width of visible region */
- RSmargininfo(w, VSIw->maxwidth - (x2 - x1), x1);
-
- VSIw->Rleft = x1;
- VSIw->Rright = x2;
-
- if (VSIw->Rbottom > VSIw->lines)
- /* don't scroll off the bottom of the screen */
- n = VSIw->Rbottom - VSIw->lines;
- else
- /* scroll to new topmost line as specified */
- n = VSIw->Rtop - y1;
-
- if (n != 0)
- /* scroll vertically (assume height of region hasn't also changed) */
- if (n > 0)
- VSscrolback(w, n);
- else
- VSscrolforward(w, -n);
- else
- {
- /* just redraw separator (if it's become visible) */
- x1 = y1 = 1;
- n = 132;
- if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset))
- RSdrawsep(w, n, 1);
- /* and update vertical scroll bar limits for new height of visible region */
- RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
- } /* if */
- return(0);
- } /* VSsetrgn */
-
- int VSscrolcontrol
- (
- int w,
- int scrolon, /* whether to save lines off top */
- int offtop /* whether to save lines on clearing entire screen */
- )
- /* changes scrollback flag settings for a virtual screen. */
- {
- if (VSvalids(w) != 0)
- return(-3);
-
- if (scrolon > -1)
- VSIw->savelines = scrolon;
- if (offtop > -1)
- VSIw->ESscroll = offtop;
-
- return(0);
- } /* VSscrolcontrol */
-
- int VSgetrgn
- (
- int w,
- int *x1,
- int *y1,
- int *x2,
- int *y2
- )
- /* returns the current visible region for a virtual screen. */
- {
- if (VSvalids(w) != 0)
- return(-3);
-
- *x1 = VSIw->Rleft;
- *y1 = VSIw->Rtop;
- *x2 = VSIw->Rright;
- *y2 = VSIw->Rbottom;
-
- return(0);
- } /* VSgetrgn */
-
- VSsnapshot(w)
- int w;
- /* does nothing interesting. Not used. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- return(0);
- } /* VSsnapshot */
-
- int VSmaxwidth
- (
- int w
- )
- /* returns one less than the number of columns on a virtual screen. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- return(VSIw->maxwidth);
- } /* VSmaxwidth */
-
- VSlinePtr VSIGetLineStart(w, y1)
- /* returns a pointer to the specified text line (number may be
- negative for a line in the scrollback buffer). */
- {
- VSlinePtr ptr;
- int n;
-
- if (VSvalids(w) != 0)
- return((VSlinePtr) -3);
-
- if (y1 >= 0)
- return(VSIw->linest[y1]);
-
- n = y1 - VSIw->Rtop; /* Number of lines from VISTOP to scroll forward */
- ptr = VSIw->vistop;
- while (n > 0)
- {
- n--;
- ptr = ptr->next;
- } /* while */
- while (n < 0)
- {
- n++;
- ptr = ptr->prev;
- } /* while */
- return(ptr);
- } /* VSIGetLineStart */
-
- char *VSIstrcopy(src, len, dest, table)
- char *src, *dest;
- int len, table;
- /* copies characters from *src (length len) to *dest, dropping
- trailing blanks. If table is nonzero, then this number (or more) of
- consecutive embedded blanks will be replaced with a tab. Returns a pointer
- to the position one past the last character copied to the *dest buffer. */
- {
- char *p, *tempp;
- int tblck;
-
- p = src + len - 1;
- /* skip trailing blanks */
- while ((*p == ' ') && (p >= src))
- p--;
- if (p < src)
- return(dest);
- if (!table)
- /* straight character copy */
- while (src <= p)
- *dest++ = *src++;
- else
- /* tab-replacement copy */
- while (src <= p)
- {
- while ((src <= p) && (*src != ' '))
- *dest++ = *src++;
- if (src < p)
- {
- tempp = dest; /* remember start of run of spaces */
- tblck = 0; /* length of run */
- while ((src <= p) && (*src == ' '))
- {
- *dest++ = *src++;
- tblck++;
- } /* while */
- if (tblck >= table)
- {
- *tempp++ = '\011'; /* replace first space with a tab */
- dest = tempp; /* drop remaining spaces */
- } /* if */
- } /* if */
- } /* while */
- return(dest);
- } /* VSIstrcopy */
-
- long VSgettext(w, x1, y1, x2, y2, charp, max, EOLS, table)
- int w, x1, y1, x2, y2;
- char *charp, *EOLS;
- long max;
- int table;
- /* copies a portion of text from the specified virtual screen into
- the *charp buffer. table, if nonzero, is the minimum length of
- runs of spaces to be replaced with single tabs. Returns the
- length of the copied text. max is supposed to be the maximum
- length to copy, but this is currently ignored!
- EOLS is the end-of-line sequence to insert at line boundaries.
- This is currently assumed to be exactly one character long. */
- {
- #pragma unused(max) /* !! */
- int EOLlen;
- int lx,ly, /* Upper bounds of selection */
- ux,uy; /* Lower bounds of selection */
- int maxwid;
- char *origcp;
- VSlinePtr t;
-
- if (VSvalids(w) != 0)
- return(-3);
- EOLlen = strlen(EOLS);
- maxwid = VSIw->maxwidth;
- origcp = charp;
-
- if (y1 < -VSIw->numlines)
- {
- y1 = -VSIw->numlines;
- x1 = -1;
- } /* if */
- if (y1 == y2)
- {
- /* copying no more than a single line */
- t = VSIGetLineStart(w, y1);
- if (x1 < x2) /* Order the lower and upper bounds */
- {
- ux = x1;
- uy = y1;
- lx = x2;
- ly = y2;
- }
- else
- {
- ux = x2;
- uy = y2;
- lx = x1;
- ly = y1;
- } /* if */
-
- if ((long)(lx-ux) < max)
- charp=VSIstrcopy(&t->text[ux+1], lx-ux, charp, table);
- else
- charp=VSIstrcopy(&t->text[ux+1], (int)(max - (long)(charp-origcp)), charp, table);
- if (lx == maxwid)
- *charp++ = *EOLS; /* assumes it's only one character! */
- }
- else
- {
- /* copying more than one line */
- if (y1 < y2) /* Order the lower and upper bounds */
- {
- ux = x1;
- uy = y1;
- lx = x2;
- ly = y2;
- }
- else
- {
- ux = x2;
- uy = y2;
- lx = x1;
- ly = y1;
- } /* if */
- t = VSIGetLineStart(w, uy);
- if (((long) (maxwid-ux) < max))
- charp=VSIstrcopy(&t->text[ux+1],maxwid-ux,charp,table);
- else
- charp=VSIstrcopy(&t->text[ux+1],(int) (max-(long)(charp-origcp)),charp,table);
- *charp++ = *EOLS; /* assumes it's only one character! */
- uy++;
- t = t->next;
- while (uy < ly && uy < VSIw->lines)
- {
- if ((long)(maxwid+1) < max)
- charp=VSIstrcopy(t->text,maxwid+1,charp, table);
- else
- charp=VSIstrcopy(t->text,(int)(max - (long) (charp-origcp)),charp, table);
- *charp++=*EOLS;
- t=t->next;
- uy++;
- } /* while */
- if (ly > VSIw->lines)
- lx = maxwid;
-
- if ((long) (lx+1) < max)
- charp=VSIstrcopy(t->text,lx+1,charp,table);
- else
- charp=VSIstrcopy(t->text,(int)(max - (long)(charp-origcp)),charp,table);
-
- if (lx >= maxwid)
- *charp++ = *EOLS; /* assumes it's only one character! */
- } /* if */
- return(charp - origcp);
- } /* VSgettext */
-
- int VSgetlines
- (
- int w
- )
- /* returns the number of lines in a virtual screen. */
- {
- if (VSvalids(w) != 0)
- return(-3);
- return(VSIw->lines + 1);
- } /* VSgetlines */
-
- int VSsetlines
- (
- int w, /* window number */
- int lines /* new number of lines */
- )
- /* sets the number of lines in a virtual screen, reallocating text
- and attribute arrays accordingly. Returns the new number of lines
- on success. */
- {
- VSlineArray attrst, linest; /* For storage of old ones */
- VSlinePtr line; /* pointer to a line */
- int i, j, oldlines;
- char *temp, *tempa;
-
- if (VSvalids(w) != 0)
- return(-3);
-
- lines -= 1; /* Correct for internal use */
- oldlines = VSIw->lines;
- if (lines == oldlines)
- /* no change */
- return(0);
-
- VSIw->x = 0;
- VSIw->y = 0;
- VSIcurson(w, VSIw->x, VSIw->y, 1); /* keeps cursor from pointing outside of window */
-
- /* VSIw->scrntop = VSIw->linest[0]; */
- VSIw->vistop = VSIw->scrntop; /* Force view to the top of the screen */
- /* VSIlistndx(VSIw->scrntop, VSIw->attrst[0]); */
- attrst = VSIw->attrst; /* save old screen arrays */
- linest = VSIw->linest;
- /* allocate new screen buffers for text and attributes */
- VSIw->linest = VSInewlinearray(lines + 1);
- if (!VSIw->linest)
- {
- /* aarrgghh -- out of memory */
- VSIw->linest = linest;
- return -2;
- } /* if */
- VSIw->attrst = VSInewlinearray(lines + 1);
- if (!VSIw->attrst)
- {
- /* aarrgghh -- out of memory */
- DisposPtr((Ptr) VSIw->linest);
- VSIw->linest = linest;
- VSIw->attrst = attrst;
- return -2;
- } /* if */
- VSIw->lines = lines; /* set new number of screen lines */
-
- VSIw->linest[0] = VSInewlines(lines + 1); /* allocate new text and attribute lines */
- VSIw->attrst[0] = VSInewlines(lines + 1);
- if (VSIw->linest[0] && VSIw->attrst[0])
- { /* mem is there */
- VSIlistndx(VSIw->linest[0], VSIw->attrst[0]); /* build the new screen arrays */
- if (VSIw->savelines)
- {
- /* save previous screen contents in scrollback buffer */
- line = linest[oldlines]->next; /* save continuation */
- linest[oldlines]->next = VSIw->linest[0];
- VSIw->linest[lines]->next = line; /* restore continuation */
- VSIw->linest[0]->prev = linest[oldlines]; /* backpointer */
- if (line) /* if there was a follower */
- line->prev = VSIw->linest[lines]; /* new prev for it */
- VSIw->numlines += oldlines; /* we made more scrollback */
- }
- else
- /* get rid of previous screen contents */
- VSIfreelinelist(linest[0]);
- }
- else
- { /* need more mem - emergency */
- if (VSIw->linest[0])
- VSIfreelinelist(VSIw->linest[0]);
- if (VSIw->attrst[0])
- VSIfreelinelist(VSIw->attrst[0]);
- VSIfreelines(); /* release them all */
- VSIw->linest[0] = VSInewlines(lines + 1); /* allocate new screen arrays */
- VSIw->attrst[0] = VSInewlines(lines + 1);
- if (!VSIw->linest[0] || !VSIw->attrst[0])
- /* aarrgghh -- still out of memory -- give up */
- /* shouldn't I free the block if I got only one? */
- return(-2);
- VSIw->buftop = VSIw->linest[0];
- VSIw->numlines = 0; /* nothing in scrollback */
- } /* if */
-
- VSIw->scrntop = VSIw->linest[0]; /* new top of screen */
- VSIw->vistop = VSIw->scrntop; /* Force a scroll to the top of the screen */
- VSIlistndx(VSIw->scrntop, VSIw->attrst[0]); /* rebuild screen arrays */
- VSIw->attrst[0]->prev = VSIw->attrst[lines]; /* Make attribute list circular */
- VSIw->attrst[lines]->next = VSIw->attrst[0];
- if (!VSIw->savelines)
- {
- /* make text line list circular to indicate no extensions */
- VSIw->linest[lines]->next = VSIw->linest[0];
- VSIw->linest[0]->prev = VSIw->linest[lines];
- } /* if */
-
- /* initialize the new screen lines to blank text and no attributes */
- for (i = 0; i <= lines; i++)
- {
- tempa = VSIw->attrst[i]->text;
- temp = VSIw->linest[i]->text;
- for (j = 0; j <= VSIw->allwidth; j++)
- {
- *temp++ = ' ';
- *tempa++ = 0;
- } /* for */
- } /* for */
- /* reset scrolling region */
- VSIw->top = 0;
- VSIw->bottom = lines;
- /* reset visible region */
- VSIw->Rtop = 0;
- VSIw->Rbottom = lines;
-
- /* dispose of old screen arrays and attribute lines */
- VSIfreelinelist(attrst[0]);
- DisposPtr((Ptr) attrst);
- DisposPtr((Ptr) linest);
-
- VSredraw(w, 0, 0, VSIw->maxwidth, lines); /* draw new blank screen */
- RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* adjust vertical scroll bar */
-
- return(VSIw->lines);
-
- } /* VSsetlines */
-